/*
 * KKStoryboard.h
 *
 *  Created on: 2013-9-15
 *      Author: wanghua
 */

#ifndef KKSTORYBOARD_H_
#define KKSTORYBOARD_H_

#include "kaka_common.h"
#include "KKEvent.h"

USING_NS_CC;

typedef enum {
	KK_EASE_LINE,
	KK_EASE_IN,
	KK_EASE_OUT,
	KK_EASE_INOUT,
	KK_EASE_SIN_IN,
	KK_EASE_SIN_OUT,
	KK_EASE_SIN_INOUT,
	KK_EASE_BOUNCE_IN,
	KK_EASE_BOUNCE_OUT,
	KK_EASE_BOUNCE_INOUT,
	KK_EASE_ELASTIC_IN,
	KK_EASE_ELASTIC_OUT,
	KK_EASE_ELASTIC_INOUT
} KKEase;

#define POSITION_TYPE_LEFT 0
#define POSITION_TYPE_RIGHT 1
#define POSITION_TYPE_BOTTOM 0
#define POSITION_TYPE_TOP 1
#define POSITION_TYPE_REL 2
#define POSITION_TYPE_CENTER 3

#define SIZE_TYPE_ABS 0
#define SIZE_TYPE_REL 1

class KKStoryboardFrame: public CCObject {

private:
	;CC_SYNTHESIZE(float,m_time,Time)
	;CC_SYNTHESIZE(float,m_duration,Duration)
	;CC_SYNTHESIZE(float,m_x,X)
	;CC_SYNTHESIZE(float,m_y,Y)
	;CC_SYNTHESIZE(short,m_xType,XType)
	;CC_SYNTHESIZE(short,m_yType,YType)
	;CC_SYNTHESIZE(float,m_xValue,XValue)
	;CC_SYNTHESIZE(float,m_yValue,YValue)
	;CC_SYNTHESIZE(float,m_width,Width)
	;CC_SYNTHESIZE(float,m_height,Height)
	;CC_SYNTHESIZE(float,m_angle,Angle)
	;CC_SYNTHESIZE(float,m_alpha,Alpha)
	;CC_SYNTHESIZE(float,m_anchorX,AnchorX)
	;CC_SYNTHESIZE(float,m_anchorY,AnchorY)
	;CC_SYNTHESIZE(float,m_skewX,SkewX)
	;CC_SYNTHESIZE(float,m_skewY,SkewY)
	;CC_SYNTHESIZE(string,m_status,Status)
	;CC_SYNTHESIZE(int,m_statusRepeat,StatusRepeat)
	;CC_SYNTHESIZE(KKEase,m_ease,Ease)
	;CC_SYNTHESIZE(float,m_easeRate,EaseRate)
	;CC_SYNTHESIZE(bool,m_visible,IsVisible)
	;CC_SYNTHESIZE(bool,m_enabled,IsEnabled)
	;CC_SYNTHESIZE(bool,m_positionRelative,IsPositionRelative)
	;CC_SYNTHESIZE(bool,m_sizeRelative,IsSizeRelative)
	;CC_SYNTHESIZE(KKEvent*,m_event,Event)
	;
public:
	KKStoryboardFrame() {
		m_event = NULL;
	}
	;

	virtual ~KKStoryboardFrame() {
	}
	;

	static KKStoryboardFrame* frameWithXml(TiXmlElement* element);

	bool initWithXml(TiXmlElement* element);

	inline float getPositionX(KKNode* kknode, float prevX);
	inline float getPositionY(KKNode* kknode, float prevY);
	inline float getSizeWidth(KKNode* kknode, float prevWidth);
	inline float getSizeHeight(KKNode* kknode, float prevHeight);
};

typedef KKMutableArray<KKStoryboardFrame*> KKFrameArray;

typedef enum {
	LOOP_REVERSE, LOOP_RESTART
} LoopMode;

class KKAnimation: public CCObject {

private:
	;CC_SYNTHESIZE_READONLY(int,m_targetId,TargetId)
	;CC_SYNTHESIZE_READONLY(const char*,m_targetName,TargetName)
	;CC_SYNTHESIZE(int,m_loop,LoopCount)
	;CC_SYNTHESIZE(LoopMode,m_loopMode,LoopMode)
	;CC_SYNTHESIZE_READONLY(KKFrameArray*,m_frames,Frames)
	;CC_SYNTHESIZE_READONLY(KKEvent*,m_endEvent,EndEvent)
	;CC_SYNTHESIZE_READONLY(KKEvent*,m_startEvent,StartEvent)
	;CC_SYNTHESIZE(int,m_tag,Tag)
	;

private:
	inline CCActionEase* getActionEase(KKStoryboardFrame* frame,
			CCAction* frameAction);
public:
	KKAnimation();

	virtual ~KKAnimation();

	static KKAnimation* animationWithXml(TiXmlElement* element);

	bool initWithXml(TiXmlElement* element);

	void start(CCNode* target, bool isStartWithReverse = false);

	CCNode* getTarget();

	void onStartAnimation(CCNode* target, void* firstFrame);
	void onUpdateSpriteAnimation(CCNode* target, void* animName);
	void onStopAnimation(CCNode* target, void* args);
};

typedef KKMutableArray<KKAnimation*> KKAnimationArray;

class KKStoryboard: public CCObject {

private:
	;CC_SYNTHESIZE_READONLY(string,m_name,Name)
	;CC_SYNTHESIZE_READONLY(KKAnimationArray*,m_animations,Animations)
	;CC_SYNTHESIZE(int,m_tag,Tag)
	;
public:
	KKStoryboard();

	virtual ~KKStoryboard();

	static KKStoryboard* storyboardWithXml(TiXmlElement* element, int tag);

	bool initWithXml(TiXmlElement* element, int tag);

	virtual void start();

	virtual void pause();

	virtual void resume();

	virtual void stop();

	virtual int numberOfRunningTarget();

	virtual bool isRunning();
};

#endif /* KKSTORYBOARD_H_ */
